home *** CD-ROM | disk | FTP | other *** search
/ The X-Philes (2nd Revision) / The X-Philes Number 1 (1995).iso / xphiles / hp95 / freyja13.exe / lha / DISPLAY.C < prev    next >
C/C++ Source or Header  |  1992-03-22  |  16KB  |  847 lines

  1. /* DISPLAY.C -- Redisplay and Display Routines
  2.  
  3.     Written March 1991 by Craig A. Finseth
  4.     Copyright 1991 by Craig A. Finseth
  5. */
  6.  
  7. #include "freyja.h"
  8.  
  9. #define WINMINHEIGHT    3
  10.  
  11. static char screen[ROWMAX][COLMAX + 1];
  12. static int screen_line_used[ROWMAX + 1] = { 0 };
  13. static int screen_line_len[ROWMAX + 1] = { 0 };
  14. static int point_row;
  15. static int mode_rest_col;
  16.  
  17. static int last_rest_col = -1;
  18. static int last_pct;
  19. static FLAG last_mod;
  20. static FLAG last_plus;
  21.  
  22. static FLAG need_screen_range;
  23.  
  24. static int divide;
  25.  
  26. static char mode_buf[COLMAX + 1];
  27. static FLAG div_shown = FALSE;
  28. #if defined(MSDOS)
  29. static int jmenu_which = -1;
  30. static int jmenu_cols[] = { 0, 6, 12, 18 };
  31. #endif
  32.  
  33. void D_Clear();        /* int row */
  34. void D_ClearScreen();    /* void */
  35. void D_ClearWind();    /* struct window *wptr */
  36. void D_IncrDisplay();    /* FLAG nested_call */
  37. void D_IncrDisplay2();    /* FLAG nested_call */
  38. void D_IncrDisplay3();    /* void */
  39. int D_InnerDisplay();    /* struct window *wptr, struct mark *point */
  40. void D_InnerDisplay2();    /* struct window *wptr; int row */
  41. void D_ScreenRange();    /* FLAG nested_call */
  42.  
  43. /* ------------------------------------------------------------ */
  44.  
  45. /* Initialize the display routines, part 1. */
  46.  
  47. void
  48. DInit1()
  49.     {
  50.     int cnt;
  51.  
  52.     num_windows = 1;        /* one window at the top */
  53.     divide = TMaxRow() - 1;
  54.  
  55.     for (cnt = 0; cnt < NUMWINDOWS; cnt++) {
  56.         windows[cnt].visible = FALSE;
  57.         windows[cnt].sstart = NULL;
  58.         windows[cnt].send = NULL;
  59.         windows[cnt].point = NULL;
  60.         }
  61.  
  62.     windows[0].visible = TRUE;
  63.     windows[0].top = 0;
  64.     windows[0].bot = TMaxRow() - 2;
  65.     windows[0].isend = FALSE;
  66.     windows[0].offset = 0;
  67.  
  68.     cwin = &windows[0];
  69.     need_screen_range = TRUE;
  70.     }
  71.  
  72.  
  73. /* ------------------------------------------------------------ */
  74.  
  75. /* Initialize the display routines, part 2. */
  76.  
  77. void
  78. DInit2()
  79.     {
  80.     windows[0].sstart = BMarkCreate();
  81.     windows[0].send = BMarkCreate();
  82.     windows[0].point = BMarkCreate();
  83.     D_ClearScreen();
  84.     }
  85.  
  86.  
  87. /* ------------------------------------------------------------ */
  88.  
  89. /* Terminate the display routines. */
  90.  
  91. void
  92. DFini()
  93.     {
  94.     }
  95.  
  96.  
  97. /* ------------------------------------------------------------ */
  98.  
  99. /* Display a message in the echo line. */
  100.  
  101. void
  102. DEcho(msg)
  103.     char *msg;
  104.     {
  105.     TSetPoint(TMaxRow() - 1, 0);
  106.     THiOn();
  107.  
  108.     strncpy(mode_buf, msg, TMaxCol() + 1);
  109.     mode_buf[TMaxCol()] = NUL;
  110.     TPutStr(mode_buf);
  111.  
  112.     TCLEOL();
  113.     THiOff();
  114.     TForce();
  115.     }
  116.  
  117.  
  118. /* ------------------------------------------------------------ */
  119.  
  120. /* Display a message in the echo line, but don't move the cursor. */
  121.  
  122. void
  123. DEchoNM(msg)
  124.     char *msg;
  125.     {
  126.     int row;
  127.     int col;
  128.  
  129.     row = TGetRow();
  130.     col = TGetCol();
  131.     DEcho(msg);
  132.     TSetPoint(row, col);
  133.     TForce();
  134.     }
  135.  
  136.  
  137. /* ------------------------------------------------------------ */
  138.  
  139. /* Display an error message */
  140.  
  141. void
  142. DError(msg)
  143.     char *msg;
  144.     {
  145.     char buf[2 * COLMAX + 1];
  146.     int row;
  147.     int col;
  148.  
  149.     row = TGetRow();
  150.     col = TGetCol();
  151.  
  152.     xsprintf(buf, ">>> %s", msg);
  153.     DEcho(buf);
  154.  
  155.     TBell();
  156.     KGetChar();
  157.  
  158.     DModeLine();
  159.     TSetPoint(row, col);
  160.     TForce();
  161.     }
  162.  
  163.  
  164. /* ------------------------------------------------------------ */
  165.  
  166. /* Update the display from the buffer */
  167.  
  168. void
  169. DIncrDisplay()
  170.     {
  171.     int cnt;
  172.  
  173.     if (need_screen_range) {
  174.         D_ScreenRange(FALSE);
  175.         DModeLine();
  176.         }
  177.     if (num_windows > 1) {
  178.         if (!div_shown) {
  179.             div_shown = TRUE;
  180.             TSetPoint(divide, 0);
  181.             THiOn();
  182.             for (cnt = 0; cnt < TMaxCol(); ++cnt)
  183.                 TPutChar('-');
  184.             THiOff();
  185.             }
  186.         }
  187.     else    div_shown = FALSE;
  188.     D_IncrDisplay(FALSE);
  189.     }
  190.  
  191.  
  192. /* ------------------------------------------------------------ */
  193.  
  194. /* Put up the menu for the Jaguar version. */
  195.  
  196. #if defined(MSDOS)
  197. void
  198. DJMenus(which)
  199.     int which;
  200.     {
  201.     int cnt;
  202.  
  203.     D_Clear(0);
  204.     D_Clear(1);
  205.     D_Clear(2);
  206. #if !defined(SYSMGR)
  207.     jmenu_which = which;
  208.     if (jmenu_which < 0) return;
  209.  
  210.     TSetPoint(0, 0);
  211.     TPutStr("Help  Open  Save  Quit");
  212.     TCLEOL();
  213.  
  214.     TSetPoint(1, 0);
  215.     TCLEOL();
  216. #endif
  217.     TSetPoint(2, 0);
  218.     for (cnt = 0; cnt < TMaxCol(); ++cnt) TPutChar('\xcd');
  219.  
  220.     TSetPoint(0, jmenu_cols[which]);
  221.     }
  222. #endif
  223.  
  224.  
  225. /* ------------------------------------------------------------ */
  226.  
  227. /* Scroll the window left. */
  228.  
  229. void
  230. DLeft()
  231.     {
  232.     if (!isuarg) uarg = BGetCol() - (TMaxCol() - HOVERLAP);
  233.     if (uarg < 0) uarg = 0;
  234.     BMakeColF(uarg);
  235.     uarg = 0;
  236.     D_ClearWind(cwin);
  237.     }
  238.  
  239.  
  240. /* ------------------------------------------------------------ */
  241.  
  242. /* Display the mode flags */
  243.  
  244. void
  245. DModeFlags()
  246.     {
  247.     long loc;
  248.     long len;
  249.     int pct;
  250.     FLAG mod;
  251.     FLAG plus;
  252.     char buf[LINEBUFFSIZE];
  253.  
  254.      if (KIsKey() == 'Y') return;
  255.  
  256.     loc = BGetLocation();
  257.     len = BGetLength(cbuf);
  258.     if (len == 0) len = 1;
  259.     pct = (loc * 100) / len;
  260.  
  261.     mod = BIsMod(cbuf);
  262.  
  263.     plus = TabIsDelete(lastkey, lasttable);
  264.  
  265.     if (last_rest_col != mode_rest_col ||
  266.         last_pct != pct ||
  267.         last_mod != mod ||
  268.         last_plus != plus) {
  269.         xsprintf(buf, " -%d%%- %s%s",
  270.             pct,
  271.             mod ? "*" : " ",
  272.             plus ? "+" : " ");
  273.  
  274.         TSetPoint(TMaxRow() - 1, mode_rest_col);
  275.         THiOn();
  276.         TPutStr(buf);
  277.         TCLEOL();
  278.         THiOff();
  279.         xstrcpy(mode_buf + max(0, min(strlen(mode_buf),
  280.             TMaxCol() - strlen(buf))), buf);
  281.         }
  282.     last_rest_col = mode_rest_col;
  283.     last_pct = pct;
  284.     last_mod = mod;
  285.     last_plus = plus;
  286.     }
  287.  
  288.  
  289. /* ------------------------------------------------------------ */
  290.  
  291. /* Display the mode line */
  292.  
  293. void
  294. DModeLine()
  295.     {
  296.     char buf[2 * COLMAX + 1];
  297.  
  298.     TSetPoint(TMaxRow() - 1, 0);
  299.     xsprintf(buf, "Freyja V1.3  %s ", cbuf->fname);
  300.  
  301.     mode_rest_col = strlen(buf);
  302.     last_rest_col = -1;
  303.     DEcho(buf);
  304.     DModeFlags();
  305.     }
  306.  
  307.  
  308. /* ------------------------------------------------------------  */
  309.  
  310. /* Put a new display on the screen. */
  311.  
  312. void
  313. DNewDisplay()
  314.     {
  315.     TClrScreen();
  316.     D_ClearScreen();
  317.     D_ScreenRange(FALSE);
  318.     div_shown = FALSE;
  319.     DModeLine();
  320.     }
  321.  
  322.  
  323. /* ------------------------------------------------------------ */
  324.  
  325. /* Return the current preferred line. */
  326.  
  327. int
  328. DPrefLine()
  329.     {
  330.     return((PREF_PCT * DWindHeight()) / 100);
  331.     }
  332.  
  333.  
  334. /* ------------------------------------------------------------ */
  335.  
  336. /* Scroll the window right. */
  337.  
  338. void
  339. DRight()
  340.     {
  341.     if (!isuarg) uarg = BGetCol() + (TMaxCol() - HOVERLAP);
  342.     if (uarg < 0) uarg = 0;
  343.     BMakeColF(uarg);
  344.     uarg = 0;
  345.     D_ClearWind(cwin);
  346.     }
  347.  
  348.  
  349. /* ------------------------------------------------------------ */
  350.  
  351. /* Center redisplay */
  352.  
  353. void
  354. DScreenRange()
  355.     {
  356.     need_screen_range = TRUE;
  357.     }
  358.  
  359.  
  360. /* ------------------------------------------------------------ */
  361.  
  362. /* Toggle the visible gray flag. */
  363.  
  364. void
  365. DTogVisGray()
  366.     {
  367.     c.g.vis_gray = !c.g.vis_gray;
  368.     DNewDisplay();
  369.     }
  370.  
  371.  
  372. /* ------------------------------------------------------------ */
  373.  
  374. /* Display an informative message in the message area and wait for a
  375. key press. */
  376.  
  377. void
  378. DView(msg)
  379.     char *msg;
  380.     {
  381.     int row;
  382.     int col;
  383.  
  384.     row = TGetRow();
  385.     col = TGetCol();
  386.     DEcho(msg);
  387.     KGetChar();
  388.     DModeLine();
  389.     TSetPoint(row, col);
  390.     TForce();
  391.     }
  392.  
  393.  
  394. /* ------------------------------------------------------------ */
  395.  
  396. /* Grow the current window. */
  397.  
  398. void
  399. DWindGrow()
  400.     {
  401.     int height;
  402.     int cnt;
  403.  
  404.     if (num_windows <= 1) return;
  405.  
  406.     D_Clear(divide);
  407.     if (cwin > &windows[0]) {    /* move divider up */
  408.         height = (cwin - 1)->bot - (cwin - 1)->top + 1;
  409.         if (uarg > height - WINMINHEIGHT) uarg = height - WINMINHEIGHT;
  410.         if (uarg >= 1) {
  411.             for (cnt = (cwin - 1)->bot - uarg + 1;
  412.                  cnt < (cwin - 1)->bot; cnt++) {
  413.                 D_Clear(cnt);
  414.                 }
  415.             divide -= uarg;
  416.             (cwin - 1)->bot -= uarg;
  417.             cwin->top -= uarg;
  418.             }
  419.         }
  420.     else    {            /* move divider down */
  421.         height = (cwin + 1)->bot - (cwin + 1)->top + 1;
  422.         if (uarg > height - WINMINHEIGHT) uarg = height - WINMINHEIGHT;
  423.         if (uarg >= 1) {
  424.             for (cnt = (cwin + 1)->top;
  425.                  cnt < (cwin + 1)->top + uarg - 1; cnt++) {
  426.                 D_Clear(cnt);
  427.                 }
  428.             divide += uarg;
  429.             cwin->bot += uarg;
  430.             (cwin + 1)->top += uarg;
  431.             }
  432.         }
  433.     div_shown = FALSE;
  434.     DModeLine();
  435.     uarg = 0;
  436.     }
  437.  
  438.  
  439. /* ------------------------------------------------------------ */
  440.  
  441. /* Return the height of the current window */
  442.  
  443. int
  444. DWindHeight()
  445.     {
  446.     return(cwin->bot - cwin->top + 1);
  447.     }
  448.  
  449.  
  450. /* ------------------------------------------------------------ */
  451.  
  452. /* Switch to one window mode. */
  453.  
  454. void
  455. DWindOne()
  456.     {
  457.     struct window *wptr;
  458.  
  459.     if (num_windows <= 1) return;
  460.  
  461.     wptr = (cwin == &windows[0]) ? &windows[1] : &windows[0];
  462.     wptr->visible = FALSE;
  463.  
  464.     BMarkDelete(wptr->sstart);
  465.     BMarkDelete(wptr->send);
  466.     BMarkDelete(wptr->point);
  467.  
  468.     D_ClearWind(wptr);
  469.     D_Clear(divide);
  470.  
  471.     num_windows = 1;
  472.     cwin->top = 0;
  473.     cwin->bot = TMaxRow() - 2;
  474.     DScreenRange();
  475.     }
  476.  
  477.  
  478. /* ------------------------------------------------------------ */
  479.  
  480. /* Switch which window we are in. */
  481.  
  482. void
  483. DWindSwap()
  484.     {
  485.     if (num_windows <= 1) return;
  486.  
  487.     BMarkToPoint(cwin->point);
  488.     cwin = (cwin == &windows[0]) ? &windows[1] : &windows[0];
  489.     BPointToMark(cwin->sstart);
  490.     BMarkToPoint(cwin->send);
  491.     BPointToMark(cwin->point);
  492.     cwin->isend = FALSE;
  493.     DScreenRange();
  494.     }
  495.  
  496.  
  497. /* ------------------------------------------------------------ */
  498.  
  499. /* Toggle between one and two window mode. */
  500.  
  501. void
  502. DWindTog()
  503.     {
  504.     if (num_windows == 1)
  505.         DWindTwo();
  506.     else    DWindOne();
  507.     }
  508.  
  509.  
  510. /* ------------------------------------------------------------ */
  511.  
  512. /* Switch to two window mode. */
  513.  
  514. void
  515. DWindTwo()
  516.     {
  517.     struct window *wptr;
  518.  
  519.     if (num_windows > 1) return;
  520.  
  521.     wptr = (cwin == &windows[0]) ? &windows[1] : &windows[0];
  522.     wptr->visible = TRUE;
  523.  
  524.     divide = (TMaxRow() - 2) / 2;
  525.     cwin->top = 0;
  526.     cwin->bot = divide - 1;
  527.     wptr->top = divide + 1;
  528.     wptr->bot = TMaxRow() - 2;
  529.     wptr->offset = cwin->offset;
  530.  
  531.     D_ClearWind(wptr);
  532.  
  533.     wptr->point = BMarkCreate();
  534.     BMarkSwap(cwin->sstart);
  535.     wptr->sstart = BMarkCreate();
  536.     wptr->send = BMarkCreate();
  537.     wptr->isend = FALSE;
  538.     BMarkSwap(cwin->sstart);
  539.  
  540.     num_windows = 2;
  541.     DScreenRange();
  542.     }
  543.  
  544.  
  545. /* ------------------------------------------------------------ */
  546.  
  547. /* Switch to two window mode, but go to the other window. */
  548.  
  549. void
  550. DWindTwoO()
  551.     {
  552.     DWindTwo();
  553.     DWindSwap();
  554.     }
  555.  
  556.  
  557. /* ------------------------------------------------------------ */
  558.  
  559. /* Clear the row. */
  560.  
  561. void
  562. D_Clear(row)
  563.     int row;
  564.     {
  565.     BMarkSetMod(BMarkScreen(row));
  566.     screen_line_len[row] = 0;
  567.     screen_line_used[row] = TMaxCol() + 1;
  568.     }
  569.  
  570.  
  571.  
  572. /* ------------------------------------------------------------ */
  573.  
  574. /* Clear the screen. */
  575.  
  576. void
  577. D_ClearScreen()
  578.     {
  579.     int cnt;
  580.  
  581.     for (cnt = 0; cnt < TMaxRow() - 1; cnt++) {
  582.         D_Clear(cnt);
  583.         }
  584.     }
  585.  
  586.  
  587. /* ------------------------------------------------------------ */
  588.  
  589. /* Clear the window. */
  590.  
  591. void
  592. D_ClearWind(wptr)
  593.     struct window *wptr;
  594.     {
  595.     int cnt;
  596.  
  597.     for (cnt = wptr->top; cnt <= wptr->bot; cnt++) {
  598.         D_Clear(cnt);
  599.         }
  600.     }
  601.  
  602.  
  603. /* ------------------------------------------------------------ */
  604.  
  605. /* Actually update the display from the buffer */
  606.  
  607. void
  608. D_IncrDisplay(nested_call)
  609.     FLAG nested_call;
  610.     {
  611.     struct window *wptr;
  612.     int cnt;
  613.     FLAG ischanged = FALSE;
  614.  
  615.     cnt = BGetCol();
  616.     while (cnt < cwin->offset) {
  617.         cwin->offset -= TMaxCol() - HOVERLAP;
  618.         if (cwin->offset < 0) cwin->offset = 0;
  619.         ischanged = TRUE;
  620.         }
  621.     while (cnt >= cwin->offset + TMaxCol()) {
  622.         cwin->offset += TMaxCol() - HOVERLAP;
  623.         ischanged = TRUE;
  624.         }
  625.     if (ischanged) D_ClearWind(cwin);
  626.  
  627.     BPushState();
  628.     if (BMarkBuf(cwin->sstart) != cbuf || BIsBeforeMark(cwin->sstart) ||
  629.          (cwin->isend && BMarkBuf(cwin->send) == cbuf &&
  630.          !BIsBeforeMark(cwin->send))) {
  631.         D_ScreenRange(nested_call);
  632.         }
  633.  
  634.     BMarkToPoint(cwin->point);
  635.     BPointToMark(cwin->sstart);
  636.     cwin->isend = FALSE;
  637.     point_row = D_InnerDisplay(cwin, cwin->point);
  638.  
  639.     if (BIsBeforeMark(cwin->point) && KIsKey() != 'Y') {
  640.         D_IncrDisplay2(nested_call);
  641.         }
  642.     else    {
  643.         if (num_windows > 1) {
  644.             wptr = (cwin == &windows[0]) ? &windows[1] :
  645.                 &windows[0];
  646.             BPointToMark(wptr->sstart);
  647.             D_InnerDisplay(wptr, NULL);
  648.             }
  649.         D_IncrDisplay3();
  650.         }
  651.     }
  652.  
  653.  
  654. /* ------------------------------------------------------------ */
  655.  
  656. /* Inner part of IncrDisplay. */
  657.  
  658. void
  659. D_IncrDisplay2(nested_call)
  660.     FLAG nested_call;
  661.     {
  662.     BPointToMark(cwin->point);
  663.     D_ScreenRange(nested_call);
  664.     BPopState();
  665.     D_IncrDisplay(TRUE);
  666.     }
  667.  
  668.  
  669. /* ------------------------------------------------------------ */
  670.  
  671. /* Inner part of IncrDisplay. */
  672.  
  673. void
  674. D_IncrDisplay3()
  675.     {
  676.     int col;
  677.  
  678.     BPointToMark(cwin->point);
  679.     BPopState();
  680.     DModeFlags();
  681.     col = BGetCol() - cwin->offset;
  682.     if (col < 0) col = 0;
  683.     if (col >= TMaxCol()) col = TMaxCol() - 1;
  684.     TSetPoint(point_row, col);
  685.     }
  686.  
  687.  
  688. /* ------------------------------------------------------------ */
  689.  
  690. /* Display one window. */
  691.  
  692. int
  693. D_InnerDisplay(wptr, point)
  694.     struct window *wptr;
  695.     struct mark *point;
  696.     {
  697.     struct mark *mptr;
  698.     int row;
  699.     FLAG need_pnt = TRUE;
  700.  
  701. #if defined(MSDOS)
  702.     if (c.g.special == 'J') JDisStart();
  703. #endif
  704.     for (row = wptr->top; row <= wptr->bot && KIsKey() != 'Y'; ++row) {
  705.         mptr = BMarkScreen(row);
  706.         if (BMarkBuf(mptr) != cbuf || BMarkIsMod(mptr) ||
  707.              !BIsAtMark(mptr)) {
  708.             BMarkToPoint(mptr);
  709.             D_InnerDisplay2(wptr, row);
  710.             }
  711.         else    BPointToMark(BMarkScreen(row + 1));
  712.  
  713.         if (point != NULL && need_pnt && BMarkBuf(point) == cbuf &&
  714.              BIsAfterMark(point)) {
  715.             point_row = row;
  716.             need_pnt = FALSE;
  717.             }
  718.         }
  719.  
  720.     mptr = BMarkScreen(row);
  721.     if (BMarkBuf(mptr) != cbuf || !BIsAtMark(mptr)) BMarkSetMod(mptr);
  722.     BMarkToPoint(mptr);
  723.     if (point != NULL) {
  724.         if (KIsKey() != 'Y') {
  725.             wptr->isend = TRUE;
  726.             BMarkToPoint(wptr->send);
  727.             }
  728.         if (need_pnt) point_row = wptr->bot + 1;
  729.         }
  730. #if defined(MSDOS)
  731.     if (c.g.special == 'J') JDisEnd();
  732. #endif
  733.     return(point_row);
  734.     }
  735.  
  736.  
  737. /* ------------------------------------------------------------ */
  738.  
  739. /* Inner loop of InnerDisplay. */
  740.  
  741. void
  742. D_InnerDisplay2(wptr, row)
  743.     struct window *wptr;
  744.     int row;
  745.     {
  746.     int maxcol = TMaxCol();
  747.     int maxoff = maxcol + wptr->offset;
  748.     int col;
  749.     int chr;
  750.     char *srptr;
  751.     char *cptr;
  752.     int *sllptr;
  753.     int *sluptr;
  754.  
  755.     srptr = screen[row];
  756.     sllptr = &screen_line_len[row];
  757.     sluptr = &screen_line_used[row];
  758.  
  759.     cptr = srptr;
  760.     col = 0;
  761.  
  762.     while (cptr - srptr < *sllptr && !BIsEnd() &&
  763.          (chr = BGetChar()) != NL && chr != SNL) {
  764.         if (col >= wptr->offset) {
  765.             if (chr != *cptr) break;
  766.             *cptr++;
  767.             }
  768.         if (chr >= SP && chr <= '~')
  769.             col += 1;
  770.         else    col += TGetWidth(chr, col);
  771.         BMoveBy(1);
  772.         }
  773.  
  774.     TSetPoint(row, col > wptr->offset ? col - wptr->offset : 0);
  775.     TSetOffset(wptr->offset);
  776.     if (*sluptr <= maxcol) TAdjCol();
  777.  
  778.     while (!BIsEnd() && (chr = BGetChar()) != NL && chr != SNL &&
  779.          col < maxoff) {
  780.         if (col >= wptr->offset) *cptr++ = chr;
  781.         TPutChar(chr);
  782.         if (chr >= SP && chr <= '~')
  783.             col += 1;
  784.         else    col += TGetWidth(chr, col);
  785.         BMoveBy(1);
  786.         }
  787.     if (c.g.vis_gray && !BIsEnd() && BGetChar() == NL && col < maxoff) {
  788.         if (col >= wptr->offset) *cptr++ = VIS_NL_CHAR;
  789.         TPutChar(VIS_NL_CHAR);
  790.         col += TGetWidth(VIS_NL_CHAR, col);
  791.         }
  792.  
  793.     TSetOffset(0);
  794.  
  795.     col -= wptr->offset;
  796.     if (col < 0) col = 0;
  797.     if (col > maxcol) col = maxcol;
  798.     TSetPoint(row, col);
  799.  
  800.     if (col < *sluptr || *sllptr > cptr - srptr) TCLEOL();
  801.     *sllptr = cptr - srptr;
  802.     *sluptr = col;
  803.  
  804.     if (TGetCol() < maxcol) {
  805.         if (BIsEnd())
  806.             BInvalid();
  807.         else if (!IsNL())
  808.             SearchNLF();
  809.         else    BMoveBy(1);
  810.         }
  811.     else    {
  812.         if (!IsNL())
  813.             SearchNLF();
  814.         else    BMoveBy(1);
  815.         }
  816.     }
  817.  
  818.  
  819. /* ------------------------------------------------------------ */
  820.  
  821. /* Do the work for centering the display. */
  822.  
  823. void
  824. D_ScreenRange(nested_call)
  825.     FLAG nested_call;
  826.     {
  827.     int cnt;
  828.     int pref = DPrefLine();
  829.  
  830.     need_screen_range = FALSE;
  831.     cwin->isend = FALSE;
  832.  
  833.     BMarkToPoint(cwin->point);
  834.     if (nested_call) {
  835.         for (cnt = 0; cnt < pref + 1 && SearchNLB(); ++cnt) ;
  836.         }
  837.     else    {
  838.         for (cnt = 0; cnt < pref; ++cnt) SearchNLB();
  839.         }
  840.     CLineA();
  841.     BMarkToPoint(cwin->sstart);
  842.     BPointToMark(cwin->point);
  843.     }
  844.  
  845.  
  846. /* end of DISPLAY.C -- Redisplay and Display Routines */
  847.